package cn.jtfadmin.base.dict.service.impl;



import cn.jtfadmin.base.dict.dto.DictItemModelDTO;
import cn.jtfadmin.base.dict.dto.DictModelDTO;
import cn.jtfadmin.base.dict.service.DictEntityService;
import cn.jtfadmin.base.dict.service.DynamicDictConfig;
import cn.jtfadmin.base.dict.service.DictConfig;
import cn.jtfadmin.base.dict.service.DictService;
import cn.jtfadmin.base.lang.config.ApplicationHolder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.ResolvableType;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 字典服务实现类型
 */
@Service
@Validated
public class DictServiceImpl implements DictService,
        ApplicationListener<ContextRefreshedEvent> {
    protected Map<String, List<DictItemModelDTO>> cache = new HashMap<>();

    protected List<DictModelDTO> modelCaChe = new ArrayList<>();

    @Override
    public List<DictModelDTO> findAll(String name, String describe) {
        return modelCaChe
                .stream()
                .filter(t -> {
                    if ((StringUtils.hasText(name) && !t.getName().contains(name))

                            ||
                            (StringUtils.hasText(describe) && !t.getDescribe().contains(describe))
                    ) {
                        return false;
                    }
                    return true;
                }).collect(Collectors.toList());
    }

    @Override
    public String getDictText(@NotBlank String dictCode, @NotBlank String dictValue) {
        List<DictItemModelDTO> dictItemModelDTOList = findDictItemModelByCode(dictCode);
        if (!CollectionUtils.isEmpty(dictItemModelDTOList)) {
            for (DictItemModelDTO dto : dictItemModelDTOList) {
                if (Objects.equals(dictValue, dto.getValue())) {
                    return dto.getText();
                }
            }
        }
        return "";
    }

    @Override
    public String getDictValue(@NotBlank String dictCode, @NotBlank String dictText) {
        List<DictItemModelDTO> dictItemModelDTOList = findDictItemModelByCode(dictCode);
        if (!CollectionUtils.isEmpty(dictItemModelDTOList)) {
            for (DictItemModelDTO dto : dictItemModelDTOList) {
                if (Objects.equals(dictText, dto.getText())) {
                    return dto.getValue();
                }
            }
        }
        return "";
    }


    @Override
    public List<DictItemModelDTO> findDictItemModelByCode(@NotBlank String dictCode) {
        List<DictItemModelDTO> result = cache.getOrDefault(dictCode, Collections.emptyList());
        if (CollectionUtils.isEmpty(result)) {
            {
                String[] beanNamesForType = ApplicationHolder.getApplicationContext().getBeanNamesForType(DynamicDictConfig.class);
                for (String beanName : beanNamesForType) {
                    DynamicDictConfig bean = ApplicationHolder.getApplicationContext().getBean(beanName, DynamicDictConfig.class);
                    if (bean.getDictCode().contains(dictCode)) {
                        List<DictModelDTO> initDict = bean.getInitDict();
                        for (DictModelDTO dictModelDTO : initDict) {
                            if (dictModelDTO.getName().equals(dictCode)) {
                                return dictModelDTO.getItemModelDTOList();
                            }
                        }

                    }
                }
            }
            {
                String[] beanNamesForType = ApplicationHolder.getApplicationContext().getBeanNamesForType(DictEntityService.class);
                for (String beanName : beanNamesForType) {
                    DictEntityService bean = ApplicationHolder.getApplicationContext().getBean(beanName, DictEntityService.class);
                    if (bean.getEntityClass().getSimpleName().equals(dictCode)) {
                        return bean.findDictModelList(null);

                    }
                }
            }

        }
        return result;
    }


    /**
     * 初始化字典配置
     *
     * @param event 项目启动
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 获取容器
        ApplicationContext applicationContext = event.getApplicationContext();
        if (applicationContext.getParent() != null) {
            return;
        }
        List<DictModelDTO> modelCaChe = new ArrayList<>();
        // 获取配置
        String[] beanNamesForType = applicationContext.getBeanNamesForType(DictConfig.class);
        Map<String, List<DictItemModelDTO>> map = new HashMap<>();
        for (String s : beanNamesForType) {
            DictConfig bean = applicationContext.getBean(s, DictConfig.class);
            if (bean instanceof DynamicDictConfig) {
                continue;
            }
            List<DictModelDTO> initDict = bean.getInitDict();
            initDict.forEach(t -> {
                List<DictItemModelDTO> old = map.put(t.getName(), t.getItemModelDTOList());
                if (Objects.nonNull(old)) {
                    throw new RuntimeException("字典项重复" + t.getName());
                }
            });
            modelCaChe.addAll(initDict);
        }
        this.cache = map;
        this.modelCaChe = modelCaChe;
    }


}
